package com.jt.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Random;

@RestController
public class ConsumerController {
    //IOC-(资源整合-坐享其成)->Spring框架的目标(资源整合)
    //DI-依赖注入(属性注入,构造注入,set注入):注入之前要查找(依赖查找-DL)
    @Autowired //属性注入 (但是属性不能使用final修饰)
    private  RestTemplate restTemplate;//隔空取物

    //@Autowired //推荐构造注入 (假如只有一个构造方法autowired也可以省略)
    //public ConsumerController(RestTemplate restTemplate){
    //    this.restTemplate=restTemplate;
    //}

    @Value("${server.port:8080}")
    private String serverPort;
    /**
     * 基于此对象可以从nacos中动态获取服务列表,
     * 并基于内置负载均衡算法获取服务实例,
     * 这里的LoadBalancerClient是一个接口类型,
     * 实际运行spring框架会为此接口类型的变量
     * 注入一个实现类的对象.
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    /**
     * 定义服务调用,在此方法中我们通过restTemplate基于指定url
     * 调用远端服务.
     * @return
     */
    //http://ip:port/consumer/doRestEcho1
    @GetMapping("/consumer/doRestEcho1")
    public String doRestEcho01(){
        //定义远端服务的url地址
        String url="http://localhost:8081/provider/echo/{msg}";
        //基于RestTemplate借助http协议向远端服务发起Get请求
        return restTemplate.getForObject(url,
                String.class,serverPort);//String.class为url对应服务的响应结果类型
    }

    /**
     * 负载均衡方式的服务调用
     * @return
     */
    //http://ip:port/consumer/doRestEcho2
    @GetMapping("/consumer/doRestEcho2")
    public String doRestEcho02(){
        //方案1:自己写负载均衡算法
        //定义远端服务的url地址
        //String url1="http://localhost:8081/provider/echo/{msg}";
        //String url2="http://localhost:8082/provider/echo/{msg}";
        //String[] urlArray={url1,url2};
        //String url=urlArray[new Random().nextInt(urlArray.length)];
        //基于RestTemplate借助http协议向远端服务发起Get请求
        //return restTemplate.getForObject(url,
                //String.class,serverPort);//String.class为url对应服务的响应结果类型

        //方案2:从nacos中动态获取服务列表,并基于内置负载均衡算法获取服务实例
        //1)基于服务名(这个名字是nacos注册中心中的一个服务名)获取服务实例
        ServiceInstance serviceInstance =
        loadBalancerClient.choose("sca-provider");
        //2)基于服务实例构建远端服务url
        String url="http://%s:%s/provider/echo/{msg}";
        String ip=serviceInstance.getHost();
        int port=serviceInstance.getPort();
        url=String.format(url,ip,port);
        //3)进行远端服务调用
        return restTemplate.getForObject(url,
                             String.class,serverPort);
    }

    @Autowired
    private RestTemplate loadBalancedRestTemplate;

    /**
     * 负载均衡方式的调用
     * @return
     */
    @GetMapping("/consumer/doRestEcho3")
    public String doRestEcho03(){
        //1)构建请求url,这个url使用服务名替换ip:port
        String url=String.format("http://%s/provider/echo/{msg}","sca-provider");
        //2)实现服务调用(这里的RestTemplate必须具备基于服务名查找服务实例的能力)
        return loadBalancedRestTemplate.getForObject(url,
                String.class,serverPort);
        //如上语句在发起请求会被底层拦截器拦截,拦截器拦截到请求后,
        //还是会通过loadBalancerClient对象基于服务名获取服务实例
        //只是这个过程被底层做了,我们只时进行服务调用即可.
        //所以doRestEcho03相对于doRestEcho02来讲只是做了代码的简化.
    }//知识点的学习: nacos.io
    //思路不齐,debug补齐
}
